package com.cskaoyan.javase.array._6variable;

/**
 * 可变参数指的是在形参列表中，定义好一个数据类型的可变参数，然后在调用时，可以写不确定个数的对应数据类型的实参
 * 语法：
 *      [修饰符列表] 返回值类型 方法名(形参列表,数据类型... 变量名){
 *          // 方法头
 *      }
 * 说明：
 *      1.数据类型...表示某种数据类型的可变参数，一个方法只能有一个可变参数，并且一定在形参列表的最后，不是在中间。
 *      2.可变参数的格式问题： 数据类型后面的三个点，中间可以加空格，建议不要加
 *      3.可变参数的本质是该数据类型的一个数组，在方法体中直接将它作为一个数组处理就可以了。
 *      4.带有可变参数的方法，在调用时，允许传入不确定个数的该数据类型的参数，在这个过程中，编译器会自动将这些数据封装成一个对应类型的数组，在方法体中可以直接使用这个数组。
 *      补充：像这种实现的原理不变，减少程序员工作量的语法在Java中非常常见，称之为“语法糖”，我们后面还会碰到。并且随着Java版本的提升，语法糖越来越多。
 *
 * 注意事项：
 *     1. 调用方法时，如果有一个固定参数的方法匹配的同时，也可以与可变参数的方法匹配，则选择固定参数的方法。
 *     2. 调用方法时，如果出现两个可变参数的方法都能匹配，则报错，这两个方法都无法调用了
 *    - 严格避免带有可变参数的方法发生重载，否则很容易导致方法永远无法调用
 *     3. 一个方法只能有一个可变长参数，并且这个可变长参数必须是该方法的最后一个参数。
 *
 * @since 17:06
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        /*
            add方法可以实现需求，但是需要我们在调用方法之前，需要我们先定义好一个数组。
            如果我就不想定义数组，我希望在调用方法时，想填入几个数，就填几个数
            那怎么办？
            需要使用可变参数
         */
        // System.out.println(add(1, 2, 3, 4, 5));
        // System.out.println(add(1, 2));
        System.out.println(add(1, 2));
        // Ambiguous method call: both 'Demo.add(int...)' and 'Demo.add(int, int...)' match
        // System.out.println(add(1, 2, 3));
    }

    // 需求：求不确定个数的n个(int)数的和
    // 'add(int[])' is already defined in 'com.cskaoyan.javase.array._6variable.Demo'
    /*public static int add(int[] arr) {
        // 预先定义结果变量，给出初始值0
        int sum = 0;
        // 遍历求和完事
        for (int element : arr) {
            sum += element;
        }
        return sum;
    }*/

    // 使用可变参数改造add方法
    public static int add(int... var) {
        // 预先定义结果变量，给出初始值0
        int sum = 0;
        // 遍历求和完事
        for (int element : var) {
            sum += element;
        }
        return sum;
    }

    public static int add(int a, int b) {
        return a + b;
    }

    public static int add(int a, int... var) {
        return 0;
    }

}
